# 检查必要的命令
ifeq ($(shell which jq),)
$(error "未找到jq命令。请先安装jq: 在Ubuntu上运行 'apt install jq'，在CentOS上运行 'yum install jq'")
endif

# 检查services.json文件是否存在
ifeq ($(wildcard services.json),)
$(error "未找到services.json文件。请确保该文件存在于当前目录中")
endif

# 检查services.json文件格式是否正确
ifeq ($(shell jq '.' services.json >/dev/null 2>&1; echo $$?),1)
$(error "services.json文件格式不正确，请检查JSON语法")
endif

# 基础命令
ifeq ($(OS),Windows_NT)
    RM_F := del /f /q
    RM_RF := rmdir /s /q
    MKDIR := mkdir
    DATETIME := $(shell powershell Get-Date -Format "yyyyMMdd_HHmmss")
else
    RM_F := rm -f
    RM_RF := rm -rf
    MKDIR := mkdir -p
    DATETIME := $(shell date +%Y%m%d_%H%M%S)
endif

# 版本号处理（支持 make install v=1.0.1 格式）
ifdef v
    VERSION := v$(v)
else
    VERSION ?= v1.0.0
endif

# 安装方式处理（支持 make install by=profile 格式）
ifdef by
    INSTALL_METHOD := by_$(by)
else
    INSTALL_METHOD ?= by_sysVinit
endif

# 验证安装方式是否有效
ifeq ($(filter by_systemd by_profile by_sysVinit,$(INSTALL_METHOD)),)
    $(error "无效的安装方式: $(by)。只支持: systemd, profile, sysVinit")
endif

# 从JSON配置文件中读取服务列表
SERVICES := $(shell jq -r '.start_order[]' services.json)

# 获取服务延迟时间的函数
get_delay = $(shell jq -r '.services.$(1).delay' services.json)

# 获取服务依赖的函数
get_deps = $(shell jq -r '.services.$(1).deps[]' services.json 2>/dev/null)

# 定义颜色
GREEN  := \033[0;32m
YELLOW := \033[1;33m
RED    := \033[0;31m
BLUE   := \033[0;34m
NC     := \033[0m

# 安装相关的变量
INSTALL_DIR := /usr/local/fdsmastergo
INSTALL_BIN_DIR := $(INSTALL_DIR)/bin
INSTALL_CONFIG_DIR := $(INSTALL_DIR)/config
INSTALL_DATA_DIR := $(INSTALL_DIR)/data
INSTALL_LOGS_DIR := $(INSTALL_DIR)/logs

# 安装包相关的变量
INSTALL_PKG_NAME := fdsmastergo_install
INSTALL_PKG_DIR := install/$(INSTALL_PKG_NAME)
INSTALL_PKG_SERVICE_DIR := $(INSTALL_PKG_DIR)/service
INSTALL_PKG_CMD_DIR := $(INSTALL_PKG_DIR)/cmd

# 安装方式选择
ifeq ($(INSTALL_METHOD),by_profile)
    INSTALL_SERVICE_SRC := install/run/by_profile
else ifeq ($(INSTALL_METHOD),by_systemd)
    INSTALL_SERVICE_SRC := install/run/by_systemd
else
    INSTALL_SERVICE_SRC := install/run/by_sysVinit
endif

.PHONY: all clean build run help status list install compile serial-test $(SERVICES)

# 默认目标为显示帮助信息
.DEFAULT_GOAL := help

help:
	@echo "$(YELLOW)使用方法:$(NC)"
	@echo "  make [目标] [选项]"
	@echo
	@echo "$(YELLOW)可用目标:$(NC)"
	@echo "  $(GREEN)all$(NC)      - 清理、构建并启动所有服务"
	@echo "  $(GREEN)clean$(NC)    - 清理所有服务的构建缓存"
	@echo "  $(GREEN)build$(NC)    - 构建所有服务"
	@echo "  $(GREEN)run$(NC)      - 启动所有服务"
	@echo "  $(GREEN)stop$(NC)     - 停止所有服务"
	@echo "  $(GREEN)status$(NC)   - 查看服务运行状态"
	@echo "  $(GREEN)list$(NC)     - 列出所有服务及其配置"
	@echo "  $(GREEN)install$(NC)  - 创建安装包"
	@echo "  $(GREEN)compile$(NC)  - 指定平台编译，例如:"
	@echo "               make compile GOOS=linux GOARCH=amd64"
	@echo "               make compile GOOS=windows GOARCH=amd64"
	@echo "               make compile GOOS=linux GOARCH=arm64"
	@echo "  $(GREEN)help$(NC)     - 显示此帮助信息"
	@echo "  $(GREEN)serial-test$(NC) - 构建串口设备测试工具"
	@echo
	@echo "$(YELLOW)安装包选项:$(NC)"
	@echo "  v=版本号      - 指定版本号，例如：v=1.0.1"
	@echo "  by=安装方式   - 指定安装方式，可选值："
	@echo "                  sysVinit - 使用SysVinit方式（默认）"
	@echo "                  systemd - 使用systemd方式"
	@echo "                  profile - 使用profile方式"
	@echo
	@echo "$(YELLOW)示例:$(NC)"
	@echo "  make all                           # 完整流程：清理、构建并启动所有服务"
	@echo "  make build                         # 仅构建所有服务"
	@echo "  make install                       # 创建默认版本(v1.0.0)的安装包，使用SysVinit方式"
	@echo "  make install v=1.0.1               # 创建指定版本的安装包，使用SysVinit方式"
	@echo "  make install v=1.0.1 by=systemd    # 创建指定版本的systemd方式安装包"
	@echo "  make install v=1.0.1 by=profile    # 创建指定版本的profile方式安装包"

list:
	@echo "$(YELLOW)服务列表:$(NC)"
	@echo "----------------------------------------"
	@echo "$(BLUE)启动顺序:$(NC)"
	@num=1; \
	for service in $(SERVICES); do \
		printf "  $(GREEN)%d.$(NC) %-20s" "$$num" "$$service"; \
		delay=$$(jq -r ".services.$$service.delay" services.json); \
		printf "$(YELLOW)延迟:$(NC) %-2d秒  " "$$delay"; \
		deps=$$(jq -r ".services.$$service.deps | if . == null then \"无\" else join(\", \") end" services.json); \
		printf "$(YELLOW)依赖:$(NC) %s\n" "$$deps"; \
		num=$$((num + 1)); \
	done
	@echo "----------------------------------------"
	@echo "$(YELLOW)总服务数:$(NC) $(shell echo "$(SERVICES)" | wc -w)"

all: status clean build run
	@echo "$(GREEN)所有操作已完成$(NC)"

clean: status
	@echo
	@echo "$(YELLOW)正在清理所有服务的构建缓存...$(NC)"
ifeq ($(OS),Windows_NT)
	@if exist "cmd\logs" $(RM_RF) "cmd\logs"
else
	@if [ -d "cmd/logs" ]; then $(RM_RF) cmd/logs; fi
endif
	@total=$$(echo "$(SERVICES)" | wc -w); \
	current=1; \
	for service in $(shell echo "$(SERVICES)" | tr ' ' '\n' | tac); do \
		echo "$(YELLOW)$$current/$$total$(NC) $(GREEN)清理 $$service$(NC)..."; \
		(cd cmd/$$service && $(MAKE) clean) || exit 1; \
		current=$$((current + 1)); \
	done
	@echo "$(GREEN)所有服务的构建缓存已清理完成$(NC)"

build: status
	@echo
	@echo "$(YELLOW)正在构建所有服务...$(NC)"
	@total=$$(echo "$(SERVICES)" | wc -w); \
	current=1; \
	for service in $(SERVICES); do \
		echo "$(YELLOW)$$current/$$total$(NC) $(GREEN)构建 $$service$(NC)..."; \
		(cd cmd/$$service && $(MAKE) build) || exit 1; \
		current=$$((current + 1)); \
	done
	@echo "$(GREEN)所有服务构建完成$(NC)"

run: stop
	@echo
	@echo "$(YELLOW)正在启动服务...$(NC)"
	@missing_bins=""
	@for service in $(SERVICES); do \
		if [ ! -x cmd/$$service/bin/$$service ]; then \
			missing_bins="$$missing_bins    cmd/$$service/bin/$$service\n"; \
		fi \
	done
	@if [ ! -z "$$missing_bins" ]; then \
		echo "$(RED)错误: 以下服务的可执行文件不存在:$(NC)"; \
		printf "$$missing_bins"; \
		echo "$(YELLOW)提示: 请先执行 'make build' 构建所有服务$(NC)"; \
		exit 1; \
	fi
	@total=$$(echo "$(SERVICES)" | wc -w); \
	current=1; \
	for service in $(SERVICES); do \
		echo "$(YELLOW)$$current/$$total$(NC) $(GREEN)启动 $$service$(NC)..."; \
		if pgrep -x "$$service" >/dev/null; then \
			echo "$(YELLOW)$$service已在运行中，跳过启动$(NC)"; \
		else \
			cmd/$$service/bin/$$service & \
			delay=$$(jq -r ".services.$$service.delay" services.json); \
			sleep $$delay; \
		fi; \
		current=$$((current + 1)); \
	done
	@echo "$(GREEN)所有服务已启动完成$(NC)"
	@echo "$(YELLOW)提示: 使用 'make stop' 可以停止所有服务$(NC)"

stop: status
	@echo
	@echo "$(YELLOW)正在停止所有服务...$(NC)"
	@total=$$(echo "$(SERVICES)" | wc -w); \
	current=1; \
	for service in $(shell echo "$(SERVICES)" | tr ' ' '\n' | tac); do \
		echo "$(YELLOW)$$current/$$total$(NC) $(GREEN)停止 $$service$(NC)..."; \
		if pid=$$(pgrep -f "$$service\$$"); then \
			cmd=$$(ps -p $$pid -o cmd=); \
			echo "$(YELLOW)正在停止进程: $$cmd$(NC)"; \
			pkill -f "$$service\$$" >/dev/null 2>&1 || true; \
			sleep 1; \
			if ! pgrep -f "$$service\$$" >/dev/null 2>&1; then \
				echo "$(GREEN)$$service 已停止$(NC)"; \
			else \
				echo "$(RED)$$service 停止超时，尝试强制终止...$(NC)"; \
				pkill -9 -f "$$service\$$" >/dev/null 2>&1 || true; \
				sleep 1; \
				if ! pgrep -f "$$service\$$" >/dev/null 2>&1; then \
					echo "$(GREEN)$$service 已强制停止$(NC)"; \
				else \
					echo "$(RED)$$service 无法停止$(NC)"; \
				fi \
			fi \
		else \
			echo "$(YELLOW)$$service 未在运行$(NC)"; \
		fi; \
		current=$$((current + 1)); \
	done
	@echo "$(GREEN)所有服务已停止$(NC)"

status:
	@echo "$(YELLOW)服务运行状态:$(NC)"
	@echo "----------------------------------------"
	@total=$$(echo "$(SERVICES)" | wc -w); \
	current=1; \
	for service in $(SERVICES); do \
		printf "$(YELLOW)%-3s$(NC)" "$$current."; \
		printf "$(GREEN)%-25s$(NC)" "$$service:"; \
		if pid=$$(pgrep -f "$$service$$"); then \
			path=$$(ps -p $$pid -o cmd=); \
			echo "$(GREEN)运行中 [PID: $$pid, Path: $$path]$(NC)"; \
		else \
			echo "$(RED)未运行$(NC)"; \
		fi; \
		current=$$((current + 1)); \
	done
	@echo "----------------------------------------"
	@running_count=0; \
	for service in $(SERVICES); do \
		if pgrep -f "$$service$$" >/dev/null 2>&1; then \
			running_count=$$((running_count + 1)); \
		fi \
	done; \
	total=$$(echo "$(SERVICES)" | wc -w); \
	if [ $$running_count -eq $$total ]; then \
		echo "$(GREEN)所有服务运行正常$(NC)"; \
	elif [ $$running_count -eq 0 ]; then \
		echo "$(RED)所有服务均未运行$(NC)"; \
	else \
		echo "$(YELLOW)部分服务未运行 ($$running_count/$$total)$(NC)"; \
	fi

install: $(VERSION_ARG)
	@echo "$(YELLOW)开始创建版本 $(VERSION) 的安装包...$(NC)"
	@echo "$(YELLOW)使用安装方式: $(INSTALL_METHOD)$(NC)"
	@echo "$(YELLOW)第一步：清理旧安装包...$(NC)"
ifeq ($(OS),Windows_NT)
	@if exist "$(INSTALL_PKG_DIR)" ( \
		echo "$(GREEN)清理旧的安装包目录: $(INSTALL_PKG_DIR)$(NC)" && \
		$(RM_RF) "$(INSTALL_PKG_DIR)" \
	) else ( \
		echo "$(GREEN)无旧安装包目录$(NC)" \
	)
	@if exist "install\$(INSTALL_PKG_NAME)_*.tar.gz" ( \
		echo "$(GREEN)清理旧的tar.gz文件...$(NC)" && \
		$(RM_F) "install\$(INSTALL_PKG_NAME)_*.tar.gz" \
	) else ( \
		echo "$(GREEN)无旧tar.gz文件$(NC)" \
	)
else
	@if [ -d "$(INSTALL_PKG_DIR)" ]; then \
		echo "$(GREEN)清理旧的安装包目录: $(INSTALL_PKG_DIR)$(NC)"; \
		$(RM_RF) $(INSTALL_PKG_DIR); \
	else \
		echo "$(GREEN)无旧安装包目录$(NC)"; \
	fi
	@if ls install/$(INSTALL_PKG_NAME)_*.tar.gz 1> /dev/null 2>&1; then \
		echo "$(GREEN)清理旧的tar.gz文件...$(NC)"; \
		rm -f install/$(INSTALL_PKG_NAME)_*.tar.gz; \
	else \
		echo "$(GREEN)无旧tar.gz文件$(NC)"; \
	fi
endif
	@echo "$(YELLOW)清理完成$(NC)"
	@echo "$(YELLOW)第二步：创建新安装包$(NC)"
	@echo "$(GREEN)创建目录结构$(NC)"
	@$(MKDIR) $(INSTALL_PKG_DIR)
	@$(MKDIR) $(INSTALL_PKG_SERVICE_DIR)
	@$(MKDIR) $(INSTALL_PKG_CMD_DIR)
	
	@echo "$(GREEN)复制安装脚本...$(NC)"
	@cp $(INSTALL_SERVICE_SRC)/install.sh $(INSTALL_PKG_DIR)/
	@cp $(INSTALL_SERVICE_SRC)/uninstall.sh $(INSTALL_PKG_DIR)/
	@cp $(INSTALL_SERVICE_SRC)/README.md $(INSTALL_PKG_DIR)/
	
	@echo "$(GREEN)复制服务脚本...$(NC)"
	@cp -r install/run/micro/* $(INSTALL_PKG_SERVICE_DIR)/
	@cp -r $(INSTALL_SERVICE_SRC)/* $(INSTALL_PKG_SERVICE_DIR)/
	@rm -f $(INSTALL_PKG_SERVICE_DIR)/install.sh
	@rm -f $(INSTALL_PKG_SERVICE_DIR)/uninstall.sh
	@rm -f $(INSTALL_PKG_SERVICE_DIR)/README.md
	@rm -f $(INSTALL_PKG_SERVICE_DIR)/simple_service
	
	@echo "$(GREEN)复制服务可执行文件...$(NC)"
	@total=$$(echo "$(SERVICES)" | wc -w); \
	current=1; \
	for service in $(SERVICES); do \
		echo "$(YELLOW)$$current/$$total$(NC) $(GREEN)复制 $$service$(NC)..."; \
		$(MKDIR) $(INSTALL_PKG_CMD_DIR)/$$service; \
		cp -r cmd/$$service/bin $(INSTALL_PKG_CMD_DIR)/$$service/; \
		current=$$((current + 1)); \
	done
	
	@echo "$(GREEN)复制配置文件$(NC)"
	@cp services.json $(INSTALL_PKG_DIR)/
	
	@echo "$(GREEN)设置文件权限$(NC)"
	@chmod -R 755 $(INSTALL_PKG_CMD_DIR)
	@chmod 755 $(INSTALL_PKG_SERVICE_DIR)/*
	@chmod 755 $(INSTALL_PKG_DIR)/install.sh
	@chmod 755 $(INSTALL_PKG_DIR)/uninstall.sh
	@chmod 644 $(INSTALL_PKG_DIR)/services.json
	@echo "$(YELLOW)新安装包创建完成$(NC)"
	
	@echo "$(YELLOW)第三步：打包安装目录$(NC)"
	@cd install && tar -czf "$(INSTALL_PKG_NAME)_$(VERSION)_$(DATETIME).tar.gz" $(INSTALL_PKG_NAME)
	@echo "$(YELLOW)安装目录打包完成$(NC)"
	@echo "$(YELLOW)安装包路径: install/$(INSTALL_PKG_NAME)_$(VERSION)_$(DATETIME).tar.gz$(NC)"

compile:
	@echo "$(YELLOW)设置编译平台为 $(GREEN)$(GOOS)/$(GOARCH)$(NC)"
	@sed -i.bak -e 's/^export GOOS=.*$$/export GOOS=$(GOOS)/' \
		-e 's/^export GOARCH=.*$$/export GOARCH=$(GOARCH)/' cmd/common.mk
	@rm -f cmd/common.mk.bak
	@echo "$(GREEN)编译选项已更新，可以执行 make build 开始编译$(NC)"

serial-test:
	@echo "$(YELLOW)构建串口设备测试工具...$(NC)"
	@cd cmd/serial_test && go build -o ../../bin/serial_test main.go
	@echo "$(GREEN)串口测试工具构建完成: bin/serial_test$(NC)"
	@echo "$(YELLOW)使用示例:$(NC)"
	@echo "  ./bin/serial_test -port /dev/ttyACM0 -example basic"
	@echo "  ./bin/serial_test -port /dev/ttyACM0 -example events"
	@echo "  ./bin/serial_test -help"